﻿using System;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace VMExplorer.Win32
{
	// Virtual Memory
	partial class Native
	{
		#region :: Enums ::

		public enum PAGE_STATE
		{
		//   Indicates committed pages for which physical storage has been allocated, 
		//   either in memory or in the paging file on disk.
		  MEM_COMMIT = 0x1000,
		//   Indicates reserved pages where a range of the process's virtual address space is reserved 
		//   without any physical storage being allocated. 
		//   For reserved pages, the information in the Protect member is undefined.
		  MEM_RESERVE = 0x2000,
		  MEM_DECOMMIT = 0x4000,
		  MEM_RELEASE = 0x8000,
		  MEM_RESET = 0x80000,
		//   Indicates free pages not accessible to the calling process and available to be allocated. 
		//   For free pages, the information in the AllocationBase, AllocationProtect, Protect, and Type members is undefined.
		  MEM_FREE = 0x10000,
		//   Allocates memory at the highest possible address.
		  MEM_TOP_DOWN = 0x100000,
		//   Allocates physical memory with read-write access. 
		//   This value is solely for use with Address Windowing Extensions (AWE) memory.
		//   This value must be used with MEM_RESERVE and no other values.
		  MEM_PHYSICAL = 0x400000,
		//   Allocates memory using large page support.
		//   The size and alignment must be a multiple of the large-page minimum. 
		//   To obtain this value, use the GetLargePageMinimum function.
		  MEM_LARGE_PAGES = 0x20000000
		}

		public enum PAGE_TYPE
		{
		//  Indicates that the memory pages within the region are private (that is, not shared by other processes).
		  MEM_PRIVATE = 0x20000,
		//  Indicates that the memory pages within the region are mapped into the view of a section.
		  MEM_MAPPED = 0x40000,
		//  Indicates that the memory pages within the region are mapped into the view of an image section.
		  MEM_IMAGE = 0x1000000
		}

		[Flags]
		public enum MEMORY_PROTECTION
		{
		//  Disables all access to the committed region of pages. An attempt to read from, write to, or execute the committed region results in an access violation exception, called a general protection (GP) fault.
		//  This flag is not supported by the CreateFileMapping function.
		  PAGE_NOACCESS = 0x01,

		//  Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
		  PAGE_READONLY = 0x02,

		//  Enables both read and write access to the committed region of pages.
		  PAGE_READWRITE = 0x04,

		//  Gives copy-on-write protection to the committed region of pages.
		//  This flag is not supported by the VirtualAlloc or VirtualAllocEx functions.
		  PAGE_WRITECOPY = 0x08,

		//  Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
		//  This flag is not supported by the CreateFileMapping function.
		  PAGE_EXECUTE = 0x10,

		//  Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
		//      Windows Server 2003 and Windows XP:  This attribute is not supported by the CreateFileMapping function until Windows XP SP2 and Windows Server 2003 SP1.
		  PAGE_EXECUTE_READ = 0x20,

		//  Enables execute, read, and write access to the committed region of pages.
		//      Windows Server 2003 and Windows XP:  This attribute is not supported by the CreateFileMapping function until Windows XP SP2 and Windows Server 2003 SP1.
		  PAGE_EXECUTE_READWRITE = 0x40,

		//  Enables execute, read, and write access to the committed region of image file code pages. The pages are shared read-on-write and copy-on-write.
		//  This flag is not supported by the VirtualAlloc, VirtualAllocEx, or CreateFileMapping functions.
		  PAGE_EXECUTE_WRITECOPY = 0x80,

		//  The following are modifiers that can be used in addition to the options provided in the previous table, except as noted.

		//  Pages in the region become guard pages. Any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE_VIOLATION exception and turn off the guard page status. Guard pages thus act as a one-time access alarm. For more information, see Creating Guard Pages.
		//  When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.
		//  If a guard page exception occurs during a system service, the service typically returns a failure status indicator.
		//  This value cannot be used with PAGE_NOACCESS.
		//  This flag is not supported by the CreateFileMapping function.
		  PAGE_GUARD = 0x100,

		//  Does not allow caching of the committed regions of pages in the CPU cache. The hardware attributes for the physical memory should be specified as "no cache." This is not recommended for general usage. It is useful for device drivers, for example, mapping a video frame buffer with no caching.
		//  This value cannot be used with PAGE_NOACCESS.
		//  This flag is not supported by the CreateFileMapping function.
		  PAGE_NOCACHE = 0x200,

		//  Enables write-combined memory accesses. When enabled, the processor caches memory write requests to optimize performance. Thus, if two requests are made to write to the same memory address, only the more recent write may occur.
		//  Note that the PAGE_GUARD and PAGE_NOCACHE flags cannot be specified with PAGE_WRITECOMBINE. If an attempt is made to do so, the SYSTEM_INVALID_PAGE_PROTECTION NT error code is returned by the function.
		//  This flag is not supported by the CreateFileMapping function.
		  PAGE_WRITECOMBINE = 0x400
		}

		[Flags]
		public enum ProcessAccess : uint
		{
			PROCESS_ALL = 0x001F0FFF,
			PROCESS_TERMINATE = 0x00000001,
			PROCESS_CREATE_THREAD = 0x00000002,
			PROCESS_VM_OPERATION = 0x00000008,
			PROCESS_VM_READ = 0x00000010,
			PROCESS_VM_WRITE = 0x00000020,
			PROCESS_DUPHANDLE = 0x00000040,
			PROCESS_SET_INFORMATION = 0x00000200,
			PROCESS_QUERY_INFORMATION = 0x00000400,
			PROCESS_SYNCHRONIZE = 0x00100000
		}

		#endregion
		#region :: Structs ::

		[StructLayout (LayoutKind.Sequential, Size = 28)]
		public struct MEMORY_BASIC_INFORMATION
		{
			public IntPtr BaseAddress;
			public IntPtr AllocationBase;
			public MEMORY_PROTECTION AllocationProtect;
			public uint RegionSize;
			public PAGE_STATE State;
			public MEMORY_PROTECTION Protect;
			public PAGE_TYPE Type;
		}

		#endregion
		#region :: API ::

		[DllImport ("kernel32.dll")]
		public static extern uint VirtualQueryEx (SafeProcessHandle hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, UIntPtr dwLength);

    [DllImport("kernel32.dll")]
    public static extern IntPtr VirtualAllocEx(SafeProcessHandle hProcess, IntPtr lpAddress, uint dwSize, PAGE_STATE flAllocationType, MEMORY_PROTECTION flProtect);

    [DllImport("kernel32.dll")]
    public static extern bool VirtualFreeEx(SafeProcessHandle hProcess, IntPtr lpAddress, uint dwSize, PAGE_STATE dwFreeType);

		#endregion
	}
}